package com.jiyi.retrofit;

import android.util.Log;

import com.google.gson.Gson;
import com.jiyi.bean.Result;
import com.jiyi.bean.datainput.DataInputBaseBean;
import com.jiyi.bean.datainput.new_input.BaseBuildBean;
import com.jiyi.bean.datainput.new_input.BuildListBean;
import com.jiyi.bean.datainput.new_input.DataInputStreetBean;
import com.jiyi.bean.datainput.new_input.DataInputZoneBean;
import com.jiyi.bean.datainput.new_input.DetailBuildBean;
import com.jiyi.bean.datainput.new_input.FireEquipBean;
import com.jiyi.bean.datainput.new_input.FireManageBean;
import com.jiyi.bean.datainput.new_input.FireSpaceBean;
import com.jiyi.bean.datainput.new_input.FireZoneBean;
import com.jiyi.bean.datainput.new_input.SafeEvacuationBean;
import com.jiyi.bean.datainput.new_input.SpaceLawBean;
import com.jiyi.bean.datainput.new_input.SpecialFireBean;
import com.jiyi.bean.maintenance.Task;
import com.jiyi.bean.system.UserBean;
import com.jiyi.bean.zone.RxPersonInfoBean;
import com.jiyi.bean.zone.RxUploadBean;
import com.jiyi.exception.ExceptionEngine;
import com.jiyi.exception.ServerException;
import com.swift.maintenance.base.AppConfig;

import java.util.List;

import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.functions.Function;
import io.reactivex.schedulers.Schedulers;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;

/**
 * Created by 12262 on 2016/5/31.
 */
public class HttpMethods {
    public static final String TAG = HttpMethods.class.getName();
    public static final String BASE_URL = AppConfig.TEXT_HOST;

    private static final int DEFAULT_TIMEOUT = 5;

    private Retrofit retrofit;
    private SystemService systemService;
    OkHttpClient client;

    //构造方法私有
    private HttpMethods() {
        Log.e(TAG," 创建 HttpMethods  ");
        HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {
            @Override
            public void log(String message) {
                //打印retrofit日志
                Log.i("RetrofitLog","retrofitBack = "+message);
            }
        });
        loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);

        client = new OkHttpClient.Builder()
                .addInterceptor(loggingInterceptor)
                .build();

        retrofit = new Retrofit.Builder()
                .baseUrl(BASE_URL)
                .client(client)
                .addConverterFactory(GsonConverterFactory.create())
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .build();
        systemService = retrofit.create(SystemService.class);
    }

    //在访问HttpMethods时创建单例
    private static class SingletonHolder{
        private static final HttpMethods INSTANCE = new HttpMethods();
    }

    //获取单例
    public static HttpMethods getInstance(){
        return SingletonHolder.INSTANCE;
    }

    private  class  ServerResultFunc<T> implements Function<Result<T>, T>
    {
        @Override
        public T apply(Result<T> httpResult) throws Exception {
            if (httpResult.status != 200) {
                Log.e(TAG,"ServerResultFunc status  "+httpResult.status);
                throw new ServerException(httpResult.status,httpResult.info);
            }
            Log.e(TAG,"httpResult.data:"+ new Gson().toJson(httpResult.data));
            return httpResult.data;
        }
    }

    private class HttpResultFunc<T> implements Function<Throwable, Observable<T>> {

        @Override
        public Observable<T> apply(Throwable throwable) throws Exception {
            Log.e(TAG,"HttpResultFunc" + throwable.getMessage());
            return Observable.error(ExceptionEngine.handleException(throwable));
        }
    }


    public Observable<List<UserBean>> getRegistInfo(){
        return systemService.getRegistInfo()
                .map(new ServerResultFunc<List<UserBean>>())
                .onErrorResumeNext(new HttpResultFunc<List<UserBean>>())
                .subscribeOn(Schedulers.io())
                .unsubscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }

    public Observable<Object> regist(String phone,String password,String unit,String phoneUserInput)
    {
        return systemService.regist(phone,password,unit,phoneUserInput)
                .map(new ServerResultFunc<Object>(){})
                .onErrorResumeNext(new HttpResultFunc<Object>(){})
                .subscribeOn(Schedulers.io())
                .unsubscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }

    public Observable<BuildListBean> getBuildList(String token, String  name, int page,String street,String community){
        return systemService.getBuildList(token, name,page,street,community)
                .map(new ServerResultFunc<BuildListBean>())
                .onErrorResumeNext(new HttpResultFunc<BuildListBean>())
                .subscribeOn(Schedulers.io())
                .unsubscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }

    public Observable<RxPersonInfoBean> getUserInfo(String token, String id){
        return systemService.getPersonInfo(token, id)
                .map(new ServerResultFunc<RxPersonInfoBean>())
                .onErrorResumeNext(new HttpResultFunc<RxPersonInfoBean>())
                .subscribeOn(Schedulers.io())
                .unsubscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }

    public Observable<List<Task>> getLeaderWeiBaoTask(String token, int type, int p){
        return systemService.getLeaderWeiBaoTask(token, type,p)
                .map(new ServerResultFunc<List<Task>>())
                .onErrorResumeNext(new HttpResultFunc<List<Task>>())
                .subscribeOn(Schedulers.io())
                .unsubscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }

    public Observable<List<Task>> getWeiBaoTask(String token, int type, int p){
        return systemService.getWeiBaoTask(token, type,p)
                .map(new ServerResultFunc<List<Task>>())
                .subscribeOn(Schedulers.io())
                .onErrorResumeNext(new HttpResultFunc<List<Task>>())
                .unsubscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }

    public Observable<RxUploadBean> uploadPic(MultipartBody.Part token, MultipartBody.Part file)
    {
        return systemService.uploadPicture(token,file)
                .map(new ServerResultFunc<RxUploadBean>())
                .onErrorResumeNext(new HttpResultFunc<RxUploadBean>())
                .subscribeOn(Schedulers.io())
                .unsubscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }

    public Observable<Object> addFriend(String token,String id)
    {
        Log.e(TAG,"token  "+token+"  id  "+id);
        return systemService.addFriend(token,id)
                .map(new ServerResultFunc<Object>(){})
                .onErrorResumeNext(new HttpResultFunc<Object>(){})
                .subscribeOn(Schedulers.io())
                .unsubscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }

    public Observable<BaseBuildBean> postBaseBuildInfo(MultipartBody  body)
    {
        Log.e(TAG, "postBaseBuildInfo: " + body.parts().size());
        return systemService.postBaseBuildInfo(body)
                .map(new ServerResultFunc<BaseBuildBean>(){})
                .onErrorResumeNext(new HttpResultFunc<BaseBuildBean>(){})
                .subscribeOn(Schedulers.io())
                .unsubscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }

    public Observable<BaseBuildBean> getBaseBuildInfo(String token, String id, int type)
    {
        return systemService.getBaseBuildInfo(token,id,type)
                .map(new ServerResultFunc<BaseBuildBean>(){})
                .onErrorResumeNext(new HttpResultFunc<BaseBuildBean>(){})
                .subscribeOn(Schedulers.io())
                .unsubscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }

    public Observable<DetailBuildBean> postDetailBuildInfo(String token, String id, int type, String data)
    {
        Log.e(TAG,"token  "+token+"  id  "+id+"  type  "+type+"  data  "+data);
        return systemService.postDetailBuildInfo(token,id,type,data)
                .map(new ServerResultFunc<DetailBuildBean>(){})
                .onErrorResumeNext(new HttpResultFunc<DetailBuildBean>(){})
                .subscribeOn(Schedulers.io())
                .unsubscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }

    public Observable<DetailBuildBean> getDetailBuildInfo(String token, String id, int type)
    {
        return systemService.getDetailBuildInfo(token,id,type)
                .map(new ServerResultFunc<DetailBuildBean>(){})
                .onErrorResumeNext(new HttpResultFunc<DetailBuildBean>(){})
                .subscribeOn(Schedulers.io())
                .unsubscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }

    public Observable<SpaceLawBean> postSpaceLawInfo(MultipartBody  body)
    {
        Log.e(TAG, "postSpaceLawInfo: " + body.parts().size());
        return systemService.postSpaceLawInfo(body)
                .map(new ServerResultFunc<SpaceLawBean>(){})
                .onErrorResumeNext(new HttpResultFunc<SpaceLawBean>(){})
                .subscribeOn(Schedulers.io())
                .unsubscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }

    public Observable<SpaceLawBean> getSpaceLawInfo(String token, String id, int type)
    {
        return systemService.getSpaceLawInfo(token,id,type,"license")
                .map(new ServerResultFunc<SpaceLawBean>(){})
                .onErrorResumeNext(new HttpResultFunc<SpaceLawBean>(){})
                .subscribeOn(Schedulers.io())
                .unsubscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }

    public Observable<FireSpaceBean> postFireLanesInfo(MultipartBody  body)
    {
        return systemService.postFireLanesInfo(body)
                .map(new ServerResultFunc<FireSpaceBean>(){})
                .onErrorResumeNext(new HttpResultFunc<FireSpaceBean>(){})
                .subscribeOn(Schedulers.io())
                .unsubscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }

    public Observable<FireSpaceBean> getFireLanesInfo(String token, String id, int type)
    {
        return systemService.getFireLanesInfo(token,id,type,"fire_lane_site")
                .map(new ServerResultFunc<FireSpaceBean>(){})
                .onErrorResumeNext(new HttpResultFunc<FireSpaceBean>(){})
                .subscribeOn(Schedulers.io())
                .unsubscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }

    public Observable<FireZoneBean> postFireZoneInfo(MultipartBody  body)
    {
        return systemService.postFireZoneInfo(body)
                .map(new ServerResultFunc<FireZoneBean>(){})
                .onErrorResumeNext(new HttpResultFunc<FireZoneBean>(){})
                .subscribeOn(Schedulers.io())
                .unsubscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }

    public Observable<FireZoneBean> getFireZoneInfo(String token, String id, int type)
    {
        return systemService.getFireZoneInfo(token,id,type,"partition_plane_layout")
                .map(new ServerResultFunc<FireZoneBean>(){})
                .onErrorResumeNext(new HttpResultFunc<FireZoneBean>(){})
                .subscribeOn(Schedulers.io())
                .unsubscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }

    public Observable<SafeEvacuationBean> postSafeEvacuationInfo(MultipartBody  body)
    {
        return systemService.postSafeEvacuationInfo(body)
                .map(new ServerResultFunc<SafeEvacuationBean>(){})
                .onErrorResumeNext(new HttpResultFunc<SafeEvacuationBean>(){})
                .subscribeOn(Schedulers.io())
                .unsubscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }

    public Observable<SafeEvacuationBean> getSafeEvacuationInfo(String token, String id, int type)
    {
        return systemService.getSafeEvacuationInfo(token,id,type,"safe_evacuat")
                .map(new ServerResultFunc<SafeEvacuationBean>(){})
                .onErrorResumeNext(new HttpResultFunc<SafeEvacuationBean>(){})
                .subscribeOn(Schedulers.io())
                .unsubscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }

    public Observable<FireEquipBean> postFireEquipInfo(MultipartBody  body)
    {
        return systemService.postFireEquipInfo(body)
                .map(new ServerResultFunc<FireEquipBean>(){})
                .onErrorResumeNext(new HttpResultFunc<FireEquipBean>(){})
                .subscribeOn(Schedulers.io())
                .unsubscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }

    public Observable<FireEquipBean> getFireEquipInfo(String token, String id, int type)
    {
        return systemService.getFireEquipInfo(token,id,type,"facilities_good_condition")
                .map(new ServerResultFunc<FireEquipBean>(){})
                .onErrorResumeNext(new HttpResultFunc<FireEquipBean>(){})
                .subscribeOn(Schedulers.io())
                .unsubscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }

    public Observable<SpecialFireBean> postSpecialFireInfo(MultipartBody  body)
    {
        return systemService.postSpecialFireInfo(body)
                .map(new ServerResultFunc<SpecialFireBean>(){})
                .onErrorResumeNext(new HttpResultFunc<SpecialFireBean>(){})
                .subscribeOn(Schedulers.io())
                .unsubscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }

    public Observable<SpecialFireBean> getSpecialFireInfo(String token, String id, int type)
    {
        return systemService.getSpecialFireInfo(token,id,type,"special_fire_protection")
                .map(new ServerResultFunc<SpecialFireBean>(){})
                .onErrorResumeNext(new HttpResultFunc<SpecialFireBean>(){})
                .subscribeOn(Schedulers.io())
                .unsubscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }

    public Observable<FireManageBean> postFireManageInfo(MultipartBody  body)
    {
        return systemService.postFireManageInfo(body)
                .map(new ServerResultFunc<FireManageBean>(){})
                .onErrorResumeNext(new HttpResultFunc<FireManageBean>(){})
                .subscribeOn(Schedulers.io())
                .unsubscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }

    public Observable<FireManageBean> getFireManageInfo(String token, String id, int type)
    {
        return systemService.getFireManageInfo(token,id,type,"fire_safety_management")
                .map(new ServerResultFunc<FireManageBean>(){})
                .onErrorResumeNext(new HttpResultFunc<FireManageBean>(){})
                .subscribeOn(Schedulers.io())
                .unsubscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }

    public Observable<DataInputBaseBean> getJMBaseBuildInfo(String token, String build_id)
    {
        return systemService.getJMBaseBuildInfo(token,build_id)
                .map(new ServerResultFunc<DataInputBaseBean>(){})
                .onErrorResumeNext(new HttpResultFunc<DataInputBaseBean>(){})
                .subscribeOn(Schedulers.io())
                .unsubscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }

    public Observable<List<DataInputStreetBean>> getDataInputStreet(String token){
        return systemService.getDataInputStreet(token)
                .map(new ServerResultFunc<List<DataInputStreetBean>>())
                .subscribeOn(Schedulers.io())
                .onErrorResumeNext(new HttpResultFunc<List<DataInputStreetBean>>())
                .unsubscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }

    public Observable<List<DataInputZoneBean>> getDataInputZone(String token,String streetName){
        return systemService.getDataInputZone(token,streetName)
                .map(new ServerResultFunc<List<DataInputZoneBean>>())
                .subscribeOn(Schedulers.io())
                .onErrorResumeNext(new HttpResultFunc<List<DataInputZoneBean>>())
                .unsubscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }


}
